package com.fat.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fat.entity.User;
import com.fat.annotation.NoAdmin;
import com.fat.annotation.NoToken;
import com.fat.entity.R;
import com.fat.entity.UserDto;
import com.fat.entity.UserVo;
import com.fat.service.IUserService;
import com.fat.utils.JwtUtil;
import com.fat.utils.UserHolder;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import org.springframework.beans.BeanUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author mumangguo
 * @since 2024-11-26
 */
@Tag(name = "用户管理")
@Controller
@RequestMapping("/user")
public class UserController extends BaseController {

    @Resource
    private IUserService userService;

    @Resource
    private JwtUtil jwtUtil;

    @NoAdmin
    @Operation(summary = "用户注册")
    @PostMapping("/register")
    public ResponseEntity register(@Valid @RequestBody User user) {
        //判断用户名是否重复
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", user.getUsername());
        User userDb = userService.getOne(wrapper);
        if (userDb != null) {
            return R.error("用户名已存在");
        }
        //密码加密
        user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));
        //只能注册普通用户
        user.setIsAdmin(0);
        //保存用户信息
        boolean data = userService.save(user);
        return data ? success("注册成功", null) : error("注册失败");
    }

    @NoAdmin
    @Operation(summary = "用户登录")
    @PostMapping("/login")
    public ResponseEntity login(@Valid @RequestBody UserDto userDto) {
        //判断密码是否正确
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", userDto.getUsername());
        wrapper.eq("password", DigestUtils.md5DigestAsHex(userDto.getPassword().getBytes()));
        User userDb = userService.getOne(wrapper);

        //判断账号密码
        if (userDb == null) {
            return R.error("账号或密码错误");
        }

        //登录成功
        //将id和用户名存入token
        Map tokenMap = new HashMap();
        String accessToken = jwtUtil.generateToken(userDb.getId(), userDb.getUsername());
        String refreshToken = jwtUtil.generateRefreshToken(userDb.getId());
        tokenMap.put("accessToken", accessToken);
        tokenMap.put("refreshToken", refreshToken);
        return success("登录成功", tokenMap);
    }

    @NoAdmin
    @Operation(summary = "用户注销")
    @PostMapping("/logout")
    public ResponseEntity logout(HttpServletRequest request) {
        String accessToken = request.getHeader("Authorization");
        String refreshToken = request.getHeader("refreshToken");
        //先判断token是否为null
        if (accessToken == null || refreshToken == null) {
            return error("请先登录");
        }
        //清空ThreadLocal
        UserHolder.clear();
        //根据username查询用户信息
        return success("注销成功", null);
    }

    @NoAdmin
    @Operation(summary = "刷新令牌")
    @PostMapping("/refreshToken")
    public ResponseEntity refreshToken(HttpServletRequest request) {
        try {
            String token = request.getHeader("refreshToken");
            boolean data = jwtUtil.checkToken(token);
            if (!data) {
                throw new RuntimeException("令牌已失效！");
            }
            String userId = jwtUtil.getMemberIdByJwtToken(token);
            User user = userService.getById(userId);
            String accessToken = jwtUtil.generateToken(user.getId(), user.getUsername());
            String refreshToken = jwtUtil.generateRefreshToken(user.getId());
            Map tokenMap = new HashMap();
            tokenMap.put("accessToken", accessToken);
            tokenMap.put("refreshToken", refreshToken);
            return success("刷新成功", tokenMap);
        } catch (Exception e) {
            throw new RuntimeException("令牌已失效！");
        }
    }

    @NoToken
    @NoAdmin
    @Operation(summary = "根据Token获取用户")
    @GetMapping
    public ResponseEntity getUser(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        //先判断token是否为null
        if (token == null) {
            return success(null);
        }
        //获取username
        String username = jwtUtil.getMemberNameByJwtToken(token);
        //根据username查询用户信息
        return success(userService.getOne(new QueryWrapper<User>().eq("username", username)));
    }

    @Operation(summary = "查询所有")
    @GetMapping("/list")
    public ResponseEntity list() {
        return success(userService.list());
    }

    @Operation(summary = "分页条件查询所有")
    @GetMapping("/page")
    public ResponseEntity page(@RequestParam("pageNum") Long pageNum,
                               @RequestParam("pageSize") Long pageSize,
                               User user) {
        Page<User> page = new Page<>(pageNum, pageSize);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(user.getNickname())) {
            queryWrapper.like("nickname", user.getNickname());
        }
        if (!StringUtils.isEmpty(user.getUsername())) {
            queryWrapper.like("username", user.getUsername());
        }
        if (user.getAge() != null) {
            queryWrapper.eq("age", user.getAge());
        }
        if (user.getSex() != null) {
            queryWrapper.eq("sex", user.getSex());
        }
        if (user.getIsAdmin() != null) {
            queryWrapper.eq("is_admin", user.getIsAdmin());
        }
        if (user.getCreateTime() != null) {
            queryWrapper.eq("create_time", user.getCreateTime());
        }
        return success(userService.page(page, queryWrapper));
    }

    @Operation(summary = "根据id查询")
    @GetMapping("/get/{id}")
    public ResponseEntity getById(@PathVariable Long id) {
        return R.success(userService.getOne(new QueryWrapper<User>().eq("id", id)));
    }

    @Operation(summary = "修改")
    @PutMapping
    public ResponseEntity update(@Valid @RequestBody UserVo userVo) {
        if (userVo.getPassword() != null) {
            userVo.setPassword(DigestUtils.md5DigestAsHex(userVo.getPassword().getBytes()));
        }
        User target = new User();
        BeanUtils.copyProperties(userVo, target);
        //保存用户信息
        boolean data = userService.updateById(target);
        return data ? success("修改成功", null) : error("修改失败");
    }

    @Operation(summary = "根据id删除")
    @DeleteMapping("/{id}")
    public ResponseEntity delete(@PathVariable Long id) {
        boolean data = userService.removeById(id);
        return data ? success("删除成功", null) : error("删除失败");
    }
}
